<?php

namespace app\common\model;

use app\common\service\TokenService;
use app\common\tools\Visitor;
use app\http\exception\AuthException;
use think\Db;
use think\Exception;
use think\Model;

use function error_abort;
use function get_admin_uuid;
use function md6;
use function now_time;

/**
 * 分类
 *
 * @property bool $is_delete 0=未删 1=已删
 * @property bool $sex 性别:1=男;2=女;0=未知
 * @property bool $status 0=禁用 1=启用
 * @property int $admin_id
 * @property int $group_id 用户组Id
 * @property int $store_id 门店ID
 * @property string $create_time 创建日期
 * @property string $head_pic 头像
 * @property string $last_ip 最后登录ip
 * @property string $last_login 最后登录日期
 * @property string $mobile 手机号
 * @property string $nickname 昵称
 * @property string $password 密码
 * @property string $update_time 更新日期
 * @property string $username 账号
 */
class AdminUserOauth extends Model
{

    protected $resultSetType      = 'collection';
    protected $autoWriteTimestamp = false;

    protected $pk = 'id';
    /**
     * 表名,
     */
    protected $table = 'admin';

    protected $readonly = [
        'account'
    ];

    public static function build()
    {
        return new self();
    }

    public function groups()
    {
        return $this->hasOne(AdminAuthGroup::class, 'group_id', 'group_id')
                    ->field('group_id,group_title');
    }


    public function cms_add($request)
    {
        if (
            isset($request['name']) && $this->where('name', $request['name'])
                                            ->find()) {
            throw new AuthException(sprintf('管理员名称%s不能相同', $request['name']), 403);
        }
        if (
            $request['account'] && $this->where('account', $request['account'])
                                        ->find()) {
            throw new AuthException(sprintf('管理员账号%s不能相同', $request['account']), 403);
        }
        if (
            isset($request['mobile']) && $this->where('mobile', $request['mobile'])
                                              ->find()) {
            throw new AuthException(sprintf('管理员手机号%s不能相同', $request['mobile']), 403);
        }
        $request['password'] = md6($request['password']);
        $request['create_time'] = now_time(time());
        $request['account'] = $request['account'] ?? $request['name'];
        Db::startTrans();
        try {
            $result = $this->allowField(true)
                           ->save($request);
            if ($request['admin_street']) {
                foreach ($request['admin_street'] as $v) {
                    $res = $this->addAdminStreet($this->id, $v);
                    if (!$res) {
                        Db::rollback();
                        error_abort('管辖街道数据添加失败');
                    }
                }
            }
            Db::commit();
            return $result;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw $e;
        }
    }

    public function addAdminStreet($admin_id, $street) : bool
    {
        $add['admin_id'] = $admin_id;
        $add['committees'] = $street['committees'];
        $add['street'] = $street['street'];
        $add['area'] = $street['area'];
        if (
            AdminStreet::where('area', $add['area'])
                       ->find()) {
            error_abort(sprintf('编号 %s 片区已存在关联', $add['area']));
        }
        return AdminStreet::build()
                          ->save($add);
    }

    public function cms_edit($id, $request)
    {
        $admin = $this->where('id', $id)
                      ->findOrFail();
        if ($admin['account'] === 'admin') {
            throw new AuthException('超级管理员账号禁止修改', 403);
        }

        $request['account'] = $request['name'];
        if ($request['mobile']) {
            $where = "mobile='{$request['mobile']}' and id != '{$id}'";
            $status = $this->where($where)
                           ->find();
            if ($status) {
                throw new AuthException('管理员手机号不能相同', 403);
            }
        }

        if ($request['account']) {
            $where = "account='{$request['account']}'  and id != '{$id}'";
            $status = $this->where($where)
                           ->find();
            if ($status) {
                throw new AuthException('管理员账号不能相同', 403);
            }
        }


        $request['update_time'] = now_time(time());
        if (!empty($request['password'])) {
            $request['password'] = md6($request['password']);
        } else {
            unset($request['password']);
        }
        Db::startTrans();
        try {
            $request['update_uuid'] = get_admin_uuid();
            $result = $this->where('id', $id)
                           ->find();
            $res = $result->allowField(true)
                          ->save($request);
            if ($request['admin_street']) {
                AdminStreet::where('admin_id', $id)
                           ->delete();
                foreach ($request['admin_street'] as $v) {
                    $res = $this->addAdminStreet($result->id, $v);
                    if (!$res) {
                        Db::rollback();
                        error_abort('管辖街道数据添加失败');
                    }
                }
            }

            $msg = $result ? '修改管理员信息成功' : '修改管理员信息失败';

            //记录日志
            $json = [
                'menu_name' => '权限管理',
                'operation' => $msg,
                'obj'       => json_encode($_REQUEST),
                'admin_ip'  => Visitor::getIP(),
                'explain'   => '编辑\'' . $request['account'] . '\'信息'
            ];
            //            AdminActionLog::build()
            //                          ->add($json, $userInfo);

            Db::commit();
            return $result;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new AuthException($e->getMessage(), 403);
        }
    }


    /**
     * 用户登录
     *
     * @param $request
     *
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function login($request)
    {
        $password = md6($request['password']);
        $userInfo = $this::with('adminAuthGroup')
                         ->where('username', $request['username'])
                         ->where('password', $password)
                         ->find();
        if (!$userInfo) {
            error_abort('用户不存在或账号密码错误');
        } else {
            //修改登录时间
            $userInfo->login_time = now_time(time());
            $userInfo->save();
            //用户信息
            $list = $userInfo;
            $token = TokenService::setToken($userInfo['id'], 1, $userInfo['name'], $request['platform']);
            $list->token = $token;
            //更新管理员全局变量
            set_admin_global($userInfo['id'], $userInfo);
        }
        return $list;
    }


    public function adminAuthGroup()
    {
        return $this->hasMany(AdminAuthGroup::class, 'group_id', 'group_id');
    }
}